using System.IO;
using GameFramework.Managers;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace GameFramework.GameObjects
{
    /// <summary>
    /// The abstract class for each game object.
    /// </summary>
    public abstract class GameObject : IBinarySerializable
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="GameObject"/> class.
        /// </summary>
        protected GameObject()
        {
            Visible = true;
        }

        /// <summary>
        /// Gets or sets a value indicating whether the game object is visible.
        /// </summary>
        public bool Visible { get; set; }

        #region Helper Properties

        /// <summary>
        /// Gets the game object.
        /// </summary>
        protected BaseGame Game
        {
            get { return Global.Game; } 
        }

        /// <summary>
        /// Gets the game time
        /// </summary>
        protected GameTime GameTime
        {
            get { return Global.Game.GameTime; }
        }

        /// <summary>
        /// Gets the graphics device
        /// </summary>
        protected GraphicsDevice GraphicsDevice
        {
            get { return Global.Game.GraphicsDevice; }
        }

        /// <summary>
        /// Gets the sprite batch
        /// </summary>
        protected SpriteBatch SpriteBatch
        {
            get { return Global.Game.SpriteBatch; }
        }

        /// <summary>
        /// Gets the game input
        /// </summary>
        protected GameInput Input
        {
            get { return Global.Game.Input; }
        }

        /// <summary>
        /// Gets the screen center
        /// </summary>
        protected Vector2 ScreenCenter
        {
            get { return Global.Game.ScreenCenter; }
        }

        /// <summary>
        /// Gets the screen width
        /// </summary>
        protected float ScreenWidth
        {
            get { return Global.Game.ScreenWidth; }
        }

        /// <summary>
        /// Gets the screen height
        /// </summary>
        protected float ScreenHeight
        {
            get { return Global.Game.ScreenHeight; }
        }

        /// <summary>
        /// Gets the screen manager
        /// </summary>
        protected ScreenManager ScreenManager
        {
            get { return Global.Game.ScreenManager; }
        }

        /// <summary>
        /// Gets a value indicating whether the game is running in the emulator
        /// </summary>
        protected bool IsRunningInEmulator
        {
            get { return Global.Game.IsRunningInEmulator; }
        }

        #endregion

        /// <summary>
        /// Returns <c>true</c> if the point is over the object.
        /// </summary>
        /// <param name="point">The point.</param>
        /// <returns>True if the point is over the object.</returns>
        public virtual bool IsPointOverObject(Vector2 point)
        {
            return false;
        }

        /// <summary>
        /// Update the object.
        /// </summary>
        public virtual void Update()
        {
        }

        /// <summary>
        /// Draw the object.
        /// </summary>
        public virtual void Draw()
        {
        }

        /// <summary>
        /// Tells the game object to serialize its state into the given stream.
        /// </summary>
        /// <param name="writer">The writer.</param>
        public virtual void Write(BinaryWriter writer)
        {
            writer.Write(Visible);
        }

        /// <summary>
        /// Tells the game object to deserialize its state from the given stream.
        /// </summary>
        /// <param name="reader">The reader.</param>
        public virtual void Read(BinaryReader reader)
        {
            Visible = reader.ReadBoolean();
        }
    }
}
